<script setup lang="ts">
import { start } from "nprogress";

export type DataType = {
  subTitle: string;
  describe: string;
  imgUrl: string;
};

const props = defineProps({
  // 数据
  data: {
    required: true,
    type: Array as PropType<Array<DataType>>,
    default: () => [],
  },
  // 延迟
  delay: {
    type: Number,
    default: 3000,
  },
  swiperStyle: {
    type: Object,
    default: () => {
      return {
        width: "45vw",
        "margin-top": "60px",
      };
    },
  },
});

// 定时器对象
const timer = ref<NodeJS.Timeout>();
// 当前下标
const curIndex = ref<number>(0);
// translateY值
const y = computed<number>(() => {
  return (curIndex.value / props.data.length) * 100;
});

onMounted(() => {
  start();
});

onBeforeUnmount(() => {
  clearInterval(timer.value);
});

// 开始计时
function start() {
  timer.value = setInterval(() => {
    curIndex.value =
      curIndex.value >= props.data.length - 1 ? 0 : curIndex.value + 1;
  }, props.delay);
}

// 切换显示
const handleSwitch = (index: number) => {
  if (curIndex.value == index) return;
  curIndex.value = index;
  clearInterval(timer.value);
  start();
};

defineOptions({
  name: "SwiperTitleWrap",
});
</script>

<template>
  <div class="swiper-container" v-if="data.length">
    <div class="swiper-title-wrap">
      <ul class="swiper-title" :style="`transform: translateY(-${y}%);`">
        <li
          v-for="(item, index) in data"
          :key="index"
          :class="{ active: curIndex == index }"
        >
          <h3 class="f-title f-title-night text-center sub-title">
            {{ item.subTitle }}
          </h3>
          <p class="f-describe describe-night text-center">
            {{ item.describe }}
          </p>
        </li>
      </ul>
    </div>

    <div class="flex justify-center swiper-img-container">
      <div class="swiper flex flex-col" :style="swiperStyle">
        <div class="img-list-wrap">
          <div
            class="img-list flex"
            :style="`width: ${
              data.length * 100
            }%;transform: translateX(-${y}%);`"
          >
            <img
              v-for="(img, i) in data"
              :src="img.imgUrl"
              :style="`width: ${(1 / data.length) * 100}%;`"
              :key="i"
            />
          </div>
        </div>

        <ul class="dot-list flex justify-center">
          <li
            v-for="(dot, dotIndex) in data"
            :class="{ active: curIndex == dotIndex }"
            :key="dotIndex"
            @click="handleSwitch(dotIndex)"
          ></li>
        </ul>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.swiper-title-wrap {
  height: 140px;
  .swiper-title {
    list-style-type: none;
    margin: 0;
    padding: 0;
    transition: transform 0.3s;

    li {
      margin: 0;
      padding: 0;
      height: 140px;
      transition: opacity 0.3s;
      opacity: 0;
    }

    .sub-title {
      color: #fff;
    }

    .describe-night {
      color: hsla(0, 0%, 100%, 0.5);
    }
  }
}

.swiper-img-container {
  .swiper {
    touch-action: pan-y;
    width: 100%;
    box-sizing: border-box;
    position: relative;
    .img-list-wrap {
      will-change: transform;
      border-radius: 2.2vw;
      overflow: hidden;
      width: 100%;
      .img-list {
        transition: all 0.3s;
        will-change: transform;
        border-radius: 2.2vw;
        img {
          height: auto;
          flex: 0 0 auto;
          display: block;
          -o-object-fit: cover;
          object-fit: cover;
          pointer-events: none;
        }
        img:first-child {
          border-radius: 2.2vw 0 0 2.2vw;
        }
        img:last-child {
          border-radius: 0 2.2vw 2.2vw 0;
        }
      }
    }

    .dot-list {
      position: absolute;
      bottom: -40px;
      left: 50%;
      transform: translateX(-50%);
      list-style-type: none;
      padding: 0;
      margin: 0 -10px 0;
      li {
        margin: 0 10px;
        width: 3.5vw;
        height: 0.5vw;
        background-color: #7a7a7a;
        border-radius: 1vw;
        cursor: pointer;
        position: relative;
        &::before {
          position: absolute;
          content: "";
          inset: -30px 0;
        }
      }
      li.active {
        background-color: #fff;
      }
    }
  }
}

.active {
  opacity: 1 !important;
}
</style>
